using System.Diagnostics;

namespace SharpObjects.Shared 
{
	public class Origin  
	{ 
        
		public string origin; 
        
		public Origin() 
		{ 
			StackTrace trace = new StackTrace(true); 

			if(trace.FrameCount > 0)
			{
				StackFrame frame = trace.GetFrame(0); // current frame

				System.Reflection.MethodBase method = frame.GetMethod();

				if(method.Name == ".ctor" && method.DeclaringType.Name == "Origin")
				{
					frame = trace.GetFrame(1);
					method = frame.GetMethod();
				}

				origin = string.Format("{0}: {1}", method.DeclaringType, method).Replace("+", ".");
			}
			else
			{
				origin = "Unknown";
			}
		} 

		public Origin(string sOrigin) 
		{ 
			origin = sOrigin; 
		} 
        
		public Origin(int nLevelIndex) 
		{ 
			origin = GetLevel(nLevelIndex);
		} 
        
		public override string ToString() 
		{ 
			return origin; 
		} 
        
		public static implicit operator string(Origin origin)
		{
			return origin.ToString();
		}
        
        
		public static string Here 
		{ 
			get 
			{ 
				StackTrace trace = new StackTrace(false); 

				if(trace.FrameCount > 1)
				{
					StackFrame frame = trace.GetFrame(1); 
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name).Replace("+", ".");
				}
				else
				{
					StackFrame frame = trace.GetFrame(trace.FrameCount - 1);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
			} 
		} 
        
        
		public static string OneLevelUp 
		{ 
			get 
			{ 
				StackTrace trace = new StackTrace(false);
 
				if(trace.FrameCount > 2)
				{
					StackFrame frame = trace.GetFrame(2);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
				else
				{
					StackFrame frame = trace.GetFrame(trace.FrameCount - 1);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
			} 
		} 
        
		public static string TwoLevelsUp 
		{ 
			get 
			{ 
				StackTrace trace = new StackTrace(false);
 
				if(trace.FrameCount > 3)
				{
					StackFrame frame = trace.GetFrame(3);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
				else
				{
					StackFrame frame = trace.GetFrame(trace.FrameCount - 1);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
			} 
		} 
        
		public static string ThreeLevelsUp 
		{ 
			get 
			{ 
				StackTrace trace = new StackTrace(false);
 
				if(trace.FrameCount > 4)
				{
					StackFrame frame = trace.GetFrame(4);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
				else
				{
					StackFrame frame = trace.GetFrame(trace.FrameCount - 1);
					return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
				}
			} 
		} 
        
		public static string GetLevel(int levelIndex)
		{ 
			StackTrace trace = new StackTrace(false);
 
			if(trace.FrameCount > levelIndex)
			{
				StackFrame frame = trace.GetFrame(levelIndex);
				return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
			}
			else
			{
				StackFrame frame = trace.GetFrame(trace.FrameCount - 1);
				return string.Format("{0}.{1}", frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name ).Replace("+", "."); 
			}
		}        
        
	} 
    
    
    
}
